home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr25 / me310.zip / UE310C.ZIP / MOUSE.C < prev    next >
Text File  |  1989-10-13  |  10KB  |  425 lines

  1. /*    MOUSE.C:    Mouse functionality commands
  2.             for MicroEMACS 3.10
  3.             originally written by Dave G. Conroy
  4.             modified by Jeff Lomicka and Daniel Lawrence
  5. */
  6.  
  7. #include    <stdio.h>
  8. #include    "estruct.h"
  9. #include    "etype.h"
  10. #include        "edef.h"
  11. #include    "elang.h"
  12.  
  13. #define    MNONE    0            /* Mouse commands.        */
  14. #define    MMOVE    1
  15. #define    MREG    2
  16.  
  17. #if    MOUSE
  18. NOSHARE int    lastypos = HUGE;    /* Last mouse event row.    */
  19. NOSHARE int    lastxpos = HUGE;    /* Last mouse event column.    */
  20. NOSHARE int    lastmcmd = MNONE;    /* Last mouse command.        */
  21.  
  22. /*
  23.  * Move mouse button, down. The window that the
  24.  * mouse is in is always selected (this lets you select a
  25.  * window by clicking anyplace in it, even off the end
  26.  * of the text). If the mouse points at text then dot is
  27.  * moved to that location.
  28.  */
  29. PASCAL NEAR movemd(f, n)
  30. {
  31.     register WINDOW    *wp;
  32.     register WINDOW    *lastwp;
  33.     register LINE    *lp;
  34.  
  35.     /* if anything has changed, reset the click count */
  36.     if (lastmcmd != MMOVE || lastypos!=ypos || lastxpos!=xpos)
  37.         nclicks = 0;
  38.     ++nclicks;
  39.     lastwp = mousewindow(lastypos);        /* remember last window */
  40.  
  41.     /* reset the last position */
  42.     lastypos = ypos;
  43.     lastxpos = xpos;
  44.     lastmcmd = MMOVE;
  45.  
  46.     /* if we move the mouse off the windows, don't move anything */
  47.     if ((wp=mousewindow(ypos)) == NULL)
  48.         return(FALSE);
  49.  
  50.     /* if we are on the line with the point, adjust for extended lines */
  51.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  52.         xpos += lbound;
  53.  
  54.     /* make the window the mouse points to current */
  55.     curwp = wp;
  56.     curbp = wp->w_bufp;
  57.  
  58.     /* if we changed windows, update the modelines */
  59.     if (wp != lastwp)
  60.         upmode();
  61.  
  62.     /* if we aren't off the end of the text, move the point to the mouse */
  63.     if ((lp=mouseline(wp, ypos)) != NULL) {
  64.         curwp->w_dotp = lp;
  65.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  66.     }
  67.  
  68.     return(TRUE);
  69. }
  70.  
  71.  
  72. /*    mouse-region-down:    mouse region operations
  73.  
  74.     nclicks = 0:    move cursor to mouse
  75.             set-mark
  76.  
  77.           1:    move cursor to mouse
  78.             kill-region
  79. */
  80.  
  81. PASCAL NEAR mregdown(f, n)
  82. {
  83.     register WINDOW    *wp;
  84.     register WINDOW    *lastwp;
  85.     register LINE    *lp;
  86.  
  87.     /* if anything has changed, reset the click count */
  88.     if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
  89.         nclicks = 0;
  90.     ++nclicks;
  91.     lastwp = mousewindow(lastypos);        /* remember least window */
  92.  
  93.     /* reset the last position */
  94.     lastypos = ypos;
  95.     lastxpos = xpos;
  96.     lastmcmd = MREG;
  97.  
  98.     /* if we move the mouse off the windows, don't move anything */
  99.     if ((wp=mousewindow(ypos)) == NULL)
  100.         return(FALSE);
  101.  
  102.     /* if we are on the line with the point, adjust for extended lines */
  103.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  104.         xpos += lbound;
  105.  
  106.     /* make the window the mouse points to current */
  107.     curwp = wp;
  108.     curbp = wp->w_bufp;
  109.  
  110.     /* if we changed windows, update the modelines */
  111.     if (wp != lastwp)
  112.         upmode();
  113.  
  114.     /* if we aren't off the end of the text, move the point to the mouse */
  115.     if ((lp=mouseline(wp, ypos)) != NULL) {
  116.         curwp->w_dotp = lp;
  117.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  118.     }
  119.  
  120.     /* perform the region function */
  121.     if (nclicks == 1) {
  122.         return(setmark(FALSE, 0));
  123.     } else {
  124.         lastflag &= ~CFKILL;
  125.         return(killregion(FALSE, 0));
  126.     }
  127. }
  128.  
  129. /*    mouse-region-up:    mouse region operations
  130.  
  131.     If the corrosponding downclick was on a modeline, then we
  132.     wish to delete the indicated window. Otherwise we are using
  133.     this button to copy/paste.
  134.  
  135.     nclicks = 0:    move cursor to mouse
  136.             copy-region
  137.  
  138.           1:    move cursor to mouse
  139.             yank
  140.  
  141.           3:    reset nclicks to 0
  142. */
  143.  
  144. PASCAL NEAR mregup(f, n)
  145.  
  146. {
  147.     register WINDOW    *wp;
  148.     register WINDOW    *lastwp;
  149.     register LINE *lp;
  150.     register int lastmodeline;    /* was the dowbclick on a modeline? */
  151.  
  152.     /* if anything has changed, reset the click count */
  153.     if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
  154.         nclicks = 0;
  155.     ++nclicks;
  156.     lastwp = mousewindow(lastypos);        /* remember least window */
  157.  
  158.     /* did we down click on a modeline? */
  159.     lastmodeline = ismodeline(lastwp, lastypos);
  160.  
  161.     /* reset the last position */
  162.     lastypos = ypos;
  163.     lastxpos = xpos;
  164.     lastmcmd = MREG;
  165.  
  166.     /* if we started on a modeline.... */
  167.     if (lastmodeline)
  168.         return(delwind(TRUE, 0));
  169.  
  170.     /* if we move the mouse off the windows, don't move anything */
  171.     if ((wp=mousewindow(ypos)) == NULL)
  172.         return(FALSE);
  173.  
  174.     /* if we are on the line with the point, adjust for extended lines */
  175.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  176.         xpos += lbound;
  177.  
  178.     /* make the window the mouse points to current */
  179.     curwp = wp;
  180.     curbp = wp->w_bufp;
  181.  
  182.     /* if we aren't off the end of the text, move the point to the mouse */
  183.     if ((lp=mouseline(wp, ypos)) != NULL && nclicks < 3) {
  184.         curwp->w_dotp = lp;
  185.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  186.     }
  187.  
  188.     /* if we changed windows, update the modelines, abort the new op */
  189.     if (wp != lastwp) {
  190.         upmode();
  191.         return(TRUE);
  192.     }
  193.  
  194.     /* perform the region function */
  195.     if (nclicks == 1) {
  196.         return(copyregion(FALSE, 0));
  197.     } else if (nclicks == 2) {
  198.         return(yank(FALSE, 1));
  199.     } else {
  200.         nclicks = 0;
  201.         return(TRUE);
  202.     }
  203. }
  204.  
  205. /*
  206.  * Move mouse button, up. The up click must be
  207.  * in the text region of a window. If the old click was in a
  208.  * mode line then the mode line moves to the row of the
  209.  * up click. If the old click is not in a mode line then the
  210.  * window scrolls. The code in this function is just
  211.  * too complex!
  212.  */
  213. PASCAL NEAR movemu(f, n)
  214. {
  215.     register WINDOW    *lastwp;
  216.     register WINDOW    *wp;
  217.     register int    lastmodeline;    /* was the dowbclick on a modeline? */
  218.     register int    deltay;
  219.     register int    deltax;
  220.  
  221.     /* no movement... fail the command */
  222.     if (lastypos==ypos && lastxpos==xpos)
  223.         return(FALSE);
  224.  
  225.     /* if the down click was in the bottom right corner...
  226.        then we are resizing */
  227.     if (lastypos == term.t_nrow && lastxpos + 1 == term.t_ncol) {
  228.         (*term.t_eeop)();
  229.         newwidth(TRUE, xpos + 1);
  230.         newsize(TRUE, ypos + 1);
  231.         return(TRUE);
  232.     }
  233.  
  234.     /* if the down click was not in a window.. fail the command
  235.        (for example, if we click on the command line) */
  236.     if ((lastwp=mousewindow(lastypos)) == NULL)
  237.         return(FALSE);
  238.  
  239.     /* did we down click on a modeline? */
  240.     lastmodeline = ismodeline(lastwp, lastypos);
  241.  
  242.     /* are we not in a window? fail it then */
  243.     if ((wp=mousewindow(ypos)) == NULL)
  244.         return(FALSE);
  245.  
  246.     /* how far did we move? */
  247.     deltay = lastypos-ypos;
  248.     deltax = lastxpos-xpos;
  249.     lastypos = ypos;
  250.     lastxpos = xpos;
  251.  
  252.     /* if we started on a modeline.... */
  253.     if (lastmodeline) {
  254.  
  255.         /* move the window horizontally */
  256.         if (deltax != 0 && (diagflag || deltay == 0)) {
  257.             lastwp->w_fcol += deltax;
  258.             if (lastwp->w_fcol < 0)
  259.                 lastwp->w_fcol = 0;
  260.             lastwp->w_flag |= WFMODE|WFHARD;
  261.             if (deltay == 0)
  262.                 return(TRUE);
  263.         }
  264.  
  265.         /* don't allow the bottom modeline to move */
  266.         if (lastwp->w_wndp == NULL)
  267.             return(FALSE);
  268.  
  269.         /* shrink the current window */
  270.         if (deltay > 0) {
  271.             if (lastwp != wp)
  272.                 return(FALSE);
  273.             curwp = wp;
  274.             curbp = wp->w_bufp;
  275.             return(shrinkwind(TRUE, deltay));
  276.         }
  277.  
  278.         /* or grow it */
  279.         if (deltay < 0) {
  280.             if (wp != lastwp->w_wndp)
  281.                 return(FALSE);
  282.             curwp = lastwp;
  283.             curbp = lastwp->w_bufp;
  284.             return(enlargewind(TRUE, -deltay));
  285.         }
  286.     }
  287.  
  288.     /* did we up click in a modeline? fail it them */
  289.     if (ismodeline(wp, ypos) != FALSE)
  290.         return(FALSE);
  291.  
  292.     /* we can not move outside the current window */
  293.     if (lastwp != wp)
  294.         return(FALSE);
  295.  
  296.     /* move horizontally as well? */
  297.     if (deltax != 0 && (diagflag || deltay == 0)) {
  298.         wp->w_fcol += deltax;
  299.         if (wp->w_fcol < 0)
  300.             wp->w_fcol = 0;
  301.         wp->w_flag |= WFMODE;
  302.     }
  303.  
  304.     /* and move the screen */
  305.     return(mvdnwind(TRUE, deltay));
  306. }
  307.  
  308. /*
  309.  * Return a pointer to the WINDOW structure
  310.  * for the window in which "row" is located, or NULL
  311.  * if "row" isn't in any window. The mode line is
  312.  * considered to be part of the window.
  313.  */
  314.  
  315. WINDOW *PASCAL NEAR mousewindow(row)
  316.  
  317. register int    row;
  318.  
  319. {
  320.     register WINDOW    *wp;
  321.  
  322.     wp = wheadp;
  323.     while (wp != NULL) {
  324.         if (row < wp->w_ntrows+1)
  325.             return(wp);
  326.         row -= wp->w_ntrows+1;
  327.         wp = wp->w_wndp;
  328.     }
  329.     return(NULL);
  330. }
  331.  
  332. /*
  333.  * The row "row" is a row within the window
  334.  * whose WINDOW structure is pointed to by the "wp"
  335.  * argument. Find the associated line, and return a pointer
  336.  * to it. Return NULL if the mouse is on the mode line,
  337.  * or if the mouse is pointed off the end of the
  338.  * text in the buffer.
  339.  */
  340.  
  341. LINE *PASCAL NEAR mouseline(wp, row)
  342.  
  343. register WINDOW    *wp;
  344. register int    row;
  345.  
  346. {
  347.     register LINE    *lp;
  348.  
  349.     row -= wp->w_toprow;
  350.     if (row >= wp->w_ntrows)
  351.         return(NULL);
  352.     lp = wp->w_linep;
  353.     while (row--) {
  354.         if (lp == wp->w_bufp->b_linep)    /* Hit the end.        */
  355.             return(NULL);
  356.         lp = lforw(lp);
  357.     }
  358.     return(lp);
  359. }
  360.  
  361. /*
  362.  * Return the best character offset to use
  363.  * to describe column "col", as viewed from the line whose
  364.  * LINE structure is pointed to by "lp".
  365.  */
  366.  
  367. PASCAL NEAR mouseoffset(wp, lp, col)
  368.  
  369. register WINDOW *wp;
  370. register LINE    *lp;
  371. register int    col;
  372.  
  373. {
  374.     register int    c;
  375.     register int    offset;
  376.     register int    curcol;
  377.     register int    newcol;
  378.  
  379.     offset = 0;
  380.     curcol = 0;
  381.     col += wp->w_fcol;    /* adjust for extended lines */
  382.     while (offset != llength(lp)) {
  383.         newcol = curcol;
  384.         if ((c=lgetc(lp, offset)) == '\t')
  385.             newcol += -(newcol % tabsize) + (tabsize - 1);
  386.         else if (c<32)    /* ISCTRL */
  387.             ++newcol;
  388.         ++newcol;
  389.         if (newcol > col)
  390.             break;
  391.         curcol = newcol;
  392.         ++offset;
  393.     }
  394.     return(offset);
  395. }
  396.  
  397. PASCAL NEAR ismodeline(wp, row)
  398. WINDOW    *wp;
  399. {
  400.     if (row == wp->w_toprow+wp->w_ntrows && modeflag)
  401.         return(TRUE);
  402.     return(FALSE);
  403. }
  404.  
  405. /* The mouse has been used to resize the physical window. Now we need to
  406.    let emacs know about the newsize, and have him force a re-draw
  407. */
  408.  
  409. PASCAL NEAR resizm(f, n)
  410.  
  411. int f, n;    /* these are ignored... we get the new size info from
  412.            the mouse driver */
  413. {
  414.     (*term.t_eeop)();
  415.     newwidth(TRUE, xpos);
  416.     newsize(TRUE, ypos);
  417.     return(TRUE);
  418. }
  419.  
  420. #else
  421. mousehello()
  422. {
  423. }
  424. #endif
  425.